/**
 * Copyright (c) 2020 Coder League
 * All rights reserved.
 *
 * File：WeixinInterfaceController.java
 * History:
 *         2020年12月23日: Initially created, Chrise.
 */
package club.coderleague.cfss.controller.interfaces;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import club.coderleague.cfss.annotations.PassiveRequest;
import club.coderleague.cfss.annotations.Request;
import club.coderleague.cfss.domain.beans.WebAuthContext;
import club.coderleague.cfss.domain.enums.WebAuthScene;
import club.coderleague.cfss.service.interfaces.WeixinInterfaceService;

/**
 * 微信接口控制器。
 * @author Chrise
 */
@Controller
@RequestMapping(WeixinInterfaceController.REQUEST_PREFIX)
public class WeixinInterfaceController extends InterfaceController {
	/**
	 * 请求前缀。
	 */
	public static final String REQUEST_PREFIX = InterfaceController.REQUEST_PREFIX + "/weixin";
	/**
	 * 授权过期请求后缀。
	 */
	public static final String AUTH_EXPIRE_REQUEST_SUFFIX = "/authexpire.xhtml";
	
	private static final String EM_KEY = "errorMessage";
	private static final String EM_NOT_SUPPORTED = "系统暂不支持微信访问！";
	private static final String EM_AUTH_FAILED = "请求微信授权失败！";
	private static final String EM_AUTH_EXPIRE = "微信授权已失效！";
	
	@Autowired
	private WeixinInterfaceService wiService;
	
	/**
	 * 验证开发者身份。
	 * @author Chrise 2020年12月23日
	 * @param signature 签名。
	 * @param timestamp 时间戳。
	 * @param nonce 随机数。
	 * @param echostr 随机字符串。
	 */
	@ResponseBody
	@GetMapping("/push.xhtml")
	@PassiveRequest(value = "验证开发者身份")
	public void verifyDeveloperIdentity(String signature, String timestamp, String nonce, String echostr) {
		this.wiService.verifyDeveloperIdentity(signature, timestamp, nonce, echostr, getResponse());
	}
	
	/**
	 * 处理消息。
	 * @author Chrise 2020年12月23日
	 */
	@ResponseBody
	@PostMapping("/push.xhtml")
	@PassiveRequest(value = "处理消息")
	public void handleMessage() {
		this.wiService.dispatchMessage(getRequest(), getResponse());
	}
	
	/**
	 * 前往供应商系统。
	 * @author Chrise 2020年12月23日
	 * @param model 数据模型。
	 * @return 供应商系统授权地址。
	 */
	@GetMapping("/supplier.xhtml")
	@Request("前往供应商系统")
	public String supplier(Model model) {
		return this.webAuth(new WebAuthContext(WebAuthScene.SUPPLIER_SYSTEM), model);
	}
	
	/**
	 * 前往网吧系统。
	 * @author Chrise 2020年12月23日
	 * @param model 数据模型。
	 * @return 网吧系统授权地址。
	 */
	@GetMapping("/cybercafe.xhtml")
	@Request("前往网吧系统")
	public String cybercafe(Model model) {
		return this.webAuth(new WebAuthContext(WebAuthScene.CYBERCAFE_SYSTEM), model);
	}
	
	/**
	 * 网页授权回调。
	 * @author Chrise 2020年12月23日
	 * @param code 授权代码。
	 * @param state 状态。
	 * @param model 数据模型。
	 * @return 授权完成跳转地址。
	 */
	@GetMapping("/callback.xhtml")
	@PassiveRequest(value = "网页授权回调")
	public String webAuthCallback(String code, String state, Model model) {
		String openId = this.wiService.getOpenId(code, state, getSession());
		
		if (openId == null) model.addAttribute(EM_KEY, EM_AUTH_FAILED);
		else {
			String url = this.wiService.onAuthSuccess(openId, getSession());
			if (url == null) model.addAttribute(EM_KEY, EM_AUTH_FAILED);
			else return "redirect:" + url;
		}
		
		return "/mobile/error/webauth";
	}
	
	/**
	 * 授权过期。
	 * @author Chrise 2020年12月26日
	 * @param model 数据模型。
	 * @return 错误页面路径。
	 */
	@GetMapping(AUTH_EXPIRE_REQUEST_SUFFIX)
	@PassiveRequest("授权过期")
	public String authExpire(Model model) {
		model.addAttribute(EM_KEY, EM_AUTH_EXPIRE);
		return "/mobile/error/webauth";
	}
	
	/**
	 * 获取授权代码（模拟微信公众平台）。
	 * @author Chrise 2020年12月23日
	 * @param redirect_uri 重定向地址。
	 * @param state 状态。
	 * @param model 数据模型。
	 * @return 授权回调地址。
	 */
	@GetMapping("/oauth2/authorize")
	public String getAuthCode(String redirect_uri, String state, Model model) {
		String url = this.wiService.getAuthCallbackUrl(redirect_uri, state, getRequest());
		
		if (url == null) model.addAttribute(EM_KEY, EM_AUTH_FAILED);
		else return "redirect:" + url;
		
		return "/mobile/error/webauth";
	}
	
	/**
	 * 获取开放标识（模拟微信公众平台）。
	 * @author Chrise 2020年12月23日
	 * @param code 授权代码。
	 * @return 开放标识。
	 */
	@ResponseBody
	@GetMapping("/oauth2/access_token")
	public Map<String, Object> getOpenId(String code) {
		return this.wiService.getOpenId(code);
	}
	
	/**
	 * 网页授权。
	 * @author Chrise 2020年12月23日
	 * @param context 授权上下文。
	 * @param model 数据模型。
	 * @return 授权请求地址。
	 */
	private String webAuth(WebAuthContext context, Model model) {
		getSession().setAttribute(WebAuthContext.SESSION_KEY, context);
		
		String url = this.wiService.getAuthUrl(getSession());
		
		if (url == null) model.addAttribute(EM_KEY, EM_AUTH_FAILED);
		else if ("".equals(url)) model.addAttribute(EM_KEY, EM_NOT_SUPPORTED);
		else return "redirect:" + url;
		
		return "/mobile/error/webauth";
	}
}
